package top.codestudy.recordescreen.ui;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.hjq.permissions.OnPermission;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import java.util.Arrays;
import java.util.List;

import top.codestudy.recordescreen.R;
import top.codestudy.recordescreen.commons.ToastUtil;
import top.codestudy.recordescreen.commons.Util;
import top.codestudy.recordescreen.services.RecorderService;

import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private String TAG = getClass().getSimpleName();

    private final int request_capture_code = 10;
    //m开头以下全是活动的view
    /**
     * 录制屏幕
     */
    private Button mBtnStartRecording;
    /**
     * 停止录制
     */
    private Button mBtnStopRecording;
    //非m开头的 以下全是top window view
    private View topWindowView;
    private TextView tvStartOrStopRecord;

    private MediaProjectionManager projectionManager;
    private MediaProjection mediaProjection;
    private RecorderService recorderService;
    private WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams = null;

    private boolean hasAllPermissions = false;
    private boolean isRecorderServiceStart = false;
    private int TouchSlop;
    private ServiceConnection recorderServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            RecorderService.RecorderServiceBinder recorderServiceBinder = (RecorderService.RecorderServiceBinder) service;
            recorderService = recorderServiceBinder.getRecorderService();
            isRecorderServiceStart = true;
            Log.i(TAG, "onServiceConnected: mediaProjection => " + mediaProjection);
            recorderService.startRecorder(mediaProjection);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            recorderService.stopRecorder();
            isRecorderServiceStart = false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        TouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
        projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        if (projectionManager == null) {
            ToastUtil.shortShow(this, "不能获取MediaProjectionManager实例！");
        }

    }

    private void showTopWindow() {
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        topWindowView = LayoutInflater.from(this).inflate(R.layout.inflate_top_window, null);
        tvStartOrStopRecord = topWindowView.findViewById(R.id.tv_start_or_stop_record);
        tvStartOrStopRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TextView tv = (TextView) v;
                if (tv.getText().equals("开始")) {
                    tv.setText("取消");
                } else {
                    stopRecording();
                    removeTopWindow();
                }
            }
        });
        WindowManager.LayoutParams layoutParams = getTopWindowLayoutParams();
        setTouchEventOnTopWindow(topWindowView);
        windowManager.addView(topWindowView, layoutParams);
    }

    private WindowManager.LayoutParams getTopWindowLayoutParams() {
        if (layoutParams != null) {
            return layoutParams;
        }
        this.layoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT, (int) Util.dp2px(this, 30), 0, 0, PixelFormat.TRANSPARENT);
        layoutParams.type = TYPE_APPLICATION_OVERLAY;
        layoutParams.flags =
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
        return layoutParams;
    }

    private void removeTopWindow() {
        if (topWindowView != null) {
            windowManager.removeViewImmediate(topWindowView);
        }
    }

    private void setTouchEventOnTopWindow(final View topWindowView) {

        topWindowView.setOnTouchListener(new View.OnTouchListener() {
            float lastX;
            float lastY;
            boolean isMove = true;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        isMove = true;
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        float currentX = event.getRawX();
                        float currentY = event.getRawY();
                        float apartX = currentX - lastX;
                        float apartY = currentY - lastY;
                        WindowManager.LayoutParams topWindowLayoutParams = getTopWindowLayoutParams();
                        topWindowLayoutParams.x += apartX;
                        topWindowLayoutParams.y += apartY;//- Util.dp2px(MainActivity.this,24));
                        windowManager.updateViewLayout(topWindowView, topWindowLayoutParams);
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i(TAG, "onTouch: move");
                        break;
                }
                return false;
            }
        });
    }

    private void initView() {
        mBtnStartRecording = (Button) findViewById(R.id.btn_start_recording);
        mBtnStartRecording.setOnClickListener(this);
        mBtnStopRecording = (Button) findViewById(R.id.btn_stop_recording);
        mBtnStopRecording.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.btn_start_recording:
                startRecording();
                break;
            case R.id.btn_stop_recording:
                stopRecording();
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == request_capture_code && resultCode == RESULT_OK) {
            mediaProjection = projectionManager.getMediaProjection(resultCode, data);
            Log.i(TAG, "onActivityResult: mediaProjection => " + mediaProjection);
            startRecorderService();
            showTopWindow();
            goHome();
        } else {
            ToastUtil.shortShow(this, "不能获取MediaProjection实例！");
        }
    }

    private void startRecorderService() {
        Intent intent = new Intent(this, RecorderService.class);
        bindService(intent, recorderServiceConnection, BIND_AUTO_CREATE);
    }

    private void stopRecording() {
        if (!isRecorderServiceStart) {
            return;
        }
        isRecorderServiceStart = false;
        recorderService.stopRecorder();
        unbindService(recorderServiceConnection);
    }

    private void startRecording() {
        //申请权限 先
        if (!hasAllPermissions) {
            requestPermissions();
        } else {
            Intent screenCaptureIntent = projectionManager.createScreenCaptureIntent();
            startActivityForResult(screenCaptureIntent, request_capture_code);
        }
    }

    private void goHome() {
        Intent intent = new Intent(Intent.ACTION_MAIN, null);
        intent.addCategory(Intent.CATEGORY_HOME);
        startActivity(intent);
    }

    private void requestPermissions() {
        XXPermissions.with(this)
                .constantRequest() //可设置被拒绝后继续申请，直到用户授权或者永久拒绝
                .permission(Permission.SYSTEM_ALERT_WINDOW) //支持请求6.0悬浮窗权限8.0请求安装权限
                .permission(Permission.RECORD_AUDIO)
                .request(new OnPermission() {
                    /**
                     * 有权限被同意授予时回调
                     *
                     * @param granted           请求成功的权限组
                     * @param isAll             是否全部授予了
                     */
                    @Override
                    public void hasPermission(List<String> granted, boolean isAll) {
                        hasAllPermissions = isAll;
                        if (hasAllPermissions){
                            startRecording();
                        }
                        Log.i(TAG, "hasPermission: hasAllPermissions => " + isAll);
                    }
                    /**
                     * 有权限被拒绝授予时回调
                     *
                     * @param denied            请求失败的权限组
                     * @param quick             是否有某个权限被永久拒绝了
                     */
                    @Override
                    public void noPermission(List<String> denied, boolean quick) {
                        Log.i(TAG, "noPermission: denied ==> " + Arrays.toString(denied.toArray()));
                        ToastUtil.shortShow(MainActivity.this, "请授予全部权限！");
                        if (quick) {
                            XXPermissions.gotoPermissionSettings(MainActivity.this);
                        }
                    }
                });
    }
}
